import { IPSAppPortlet, IPSControl, IPSDashboard } from '@ibiz/dynamic-model-api';
import { Util } from '../../../util';
import {
  ICtrlActionResult,
  IMobDashboardController,
  IParam,
  IUtilService,
  IViewStateParam,
  MobDashboardEvents,
} from '../../../interface';
import { AppCtrlControllerBase } from './app-ctrl-controller-base';

/**
 * 移动端数据看板部件控制器
 *
 * @class MobDashboardController
 * @extends AppCtrlControllerBase
 * @implements IMobDashboardController
 */
export class MobDashboardController extends AppCtrlControllerBase implements IMobDashboardController {
  /**
   * @description 数据看板部件实例对象
   * @type {IPSDashboard}
   * @memberof MobDashboardController
   */
  controlInstance!: IPSDashboard;

  /**
   * @description 支持看板定制
   * @type {boolean}
   * @memberof MobDashboardController
   */
  public enableCustomized!: boolean;

  /**
   * @description 自定义看板模型数据
   * @type {IParam[]}
   * @memberof MobDashboardController
   */
  public customDashboardModelData: IParam[] = [];

  /**
   * @description 是否具有自定义面板
   * @type {boolean}
   * @memberof MobDashboardController
   */
  public hasCustomized: boolean = false;

  /**
   * @description 工具服务名称
   * @type {string}
   * @memberof MobDashboardController
   */
  public utilServiceName: string = '';

  /**
   * 是否支持搜索
   *
   * @public
   * @type {(boolean)}
   * @memberof MobDashboardController
   */
  private isSearchMode: boolean = false;

  /**
   * @description 工具服务
   * @type {IUtilService}
   * @memberof MobDashboardController
   */
  public utilService?: IUtilService;

  /**
   * @description 模型id
   * @type {string}
   * @memberof MobDashboardController
   */
  public modelId: string = '';

  /**
   * @description 门户部件集合
   * @type {IParam[]}
   * @memberof MobDashboardController
   */
  public portletList: IParam[] = [];

  /**
   * @description 部件基础数据初始化
   * @memberof MobDashboardController
   */
  public ctrlBasicInit() {
    super.ctrlBasicInit();
    this.enableCustomized = this.controlInstance.enableCustomized;
    const appDataEntity = this.controlInstance.getPSAppDataEntity();
    this.modelId = `dashboard_${
      appDataEntity?.codeName?.toLowerCase() || 'app'
    }_${this.controlInstance.codeName?.toLocaleLowerCase()}`;
  }

  /**
   * @description 部件模型数据加载
   * @memberof MobDashboardController
   */
  public async ctrlModelLoad() {
    await super.ctrlModelLoad();
    await this.initUtilService();
    if (this.controlInstance.enableCustomized && !App.isPreviewMode()) {
      await this.loadPortletList();
    }
  }

  /**
   * @description 部件初始化
   * @memberof MobDashboardController
   */
  public ctrlInit() {
    super.ctrlInit();
    if (this.viewState) {
      this.viewStateEvent = this.viewState.subscribe(({ tag, action, data }: IViewStateParam) => {
        if (!Object.is(tag, this.name)) {
          return;
        }
        if (Object.is('load', action)) {
          this.isSearchMode = data?.isSearchMode;
          this.loadModel();
        }
        if (Object.is('loaddata', action)) {
          this.notifyState(data);
        }
      });
    }
  }

  /**
   * @description 初始化工具服务
   * @memberof MobDashboardController
   */
  private async initUtilService() {
    const dashboardUtil = this.controlInstance.getPSAppDynaDashboardUtil?.();
    if (dashboardUtil && dashboardUtil.codeName && !App.isPreviewMode()) {
      this.utilServiceName = dashboardUtil.codeName.toLowerCase();
      this.utilService = await App.getUtilService().getService(this.context, dashboardUtil.codeName.toLowerCase());
    }
  }

  /**
   * @description 加载门户部件集合
   * @memberof MobDashboardController
   */
  public async loadPortletList() {
    const model = App.getModel();
    const list: any = [];
    if (model?.getAllPSAppPortlets?.()?.length) {
      for (const portlet of model.getAllPSAppPortlets() as IPSAppPortlet[]) {
        // 门户部件实例
        const portletInstance = portlet.getPSControl();
        const temp: any = {
          portletCodeName: portlet.codeName,
          modelData: portletInstance,
        };
        list.push(temp);
      }
    }
    this.portletList = list;
  }

  /**
   * @description 设置已完成绘制状态
   * @param name 部件名
   * @param data 数据
   * @memberof MobDashboardController
   */
  setIsMounted(name: string = 'self', data?: any) {
    super.setIsMounted(name, data);
    if ([...this.mountedMap.values()].indexOf(false) == -1 && (this.mountedMap.size > 1)) {
      // 执行通知方法
      if (!this.isSearchMode) {
        this.notifyState(this.viewParam);
      }
    }
  }

  /**
   * @description 通知部件加载数据
   * @private
   * @param {*} data 参数
   * @memberof MobDashboardController
   */
  private notifyState(data: any) {
    const controls = this.controlInstance.getPSControls() || [];
    if (this.viewState) {
      controls.forEach((control: IPSControl) => {
        this.viewState.next({
          tag: control.name,
          action: 'load',
          data: Util.deepCopy(data),
        });
      });
    }
  }

  /**
   * @description 加载模型
   * @memberof MobDashboardController
   */
  public async loadModel() {
    try {
      if (this.enableCustomized && this.utilService) {
        const res = await this.utilService.loadModelData(Util.deepCopy(this.context), {
          modelid: this.modelId,
          utilServiceName: this.appDeCodeName?.toLowerCase(),
        });
        if (res && res.status == 200) {
          const data: any = res.data;
          if (data && data.length > 0) {
            this.customDashboardModelData = data;
            for (const model of this.customDashboardModelData) {
              model.modelData = this.getPortletInstance(model);
            }
            this.hasCustomized = true;
          } else {
            App.getNoticeService().error('数据错误');
          }
        } else {
          App.getNoticeService().error('服务异常');
        }
      }
    } catch (error) {
      App.getNoticeService().error('加载面板错误');
      this.hasCustomized = false;
    }
  }

  /**
   * @description 获取门户部件实例对象
   * @param model 模型
   * @memberof MobDashboardController
   */
  public getPortletInstance(model: any) {
    return this.portletList.find((item: any) => {
      return model.codeName === item.portletCodeName;
    })?.modelData;
  }

  /**
   * @description 处理私人定制按钮
   * @param event 源对象
   * @memberof MobDashboardController
   */
  public async handleCustom(view: IParam, event: any): Promise<ICtrlActionResult> {
    return new Promise((resolve: any, reject: any) => {
      const viewparams: any = {
        modelid: this.modelId,
        utilServiceName: this.utilServiceName,
        appdeNamePath: this.controlInstance?.getPSAppDataEntity()?.codeName || 'app',
      };
      this.loadModel()
        .then(() => {
          const param = {
            customModel: Util.deepCopy(this.customDashboardModelData),
            ...Util.deepCopy(this.context),
            ...viewparams,
          };
          App.getOpenViewService()
            .openModal(view, this.context, param)
            .subscribe((result: IParam) => {
              if (result && Object.is(result.ret, 'OK')) {
                resolve({ ret: true, data: [] });
              } else {
                reject({ ret: false, data: [] });
              }
            });
        })
        .catch((error: any) => {
          reject({ ret: false, data: [] });
        });
    });
  }

  /**
   * @description 处理部件事件
   * @param {string} controlname 部件名称
   * @param {string} action 行为
   * @param {*} data 数据
   */
  public handleCtrlEvent(controlname: string, action: string, data: any) {
    if (action == MobDashboardEvents.REFRESH_ALL) {
      this.viewState.next({
        tag: 'all-portlet',
        action: MobDashboardEvents.REFRESH_ALL,
        data: data,
      });
      return;
    }
    super.handleCtrlEvent(controlname, action, data);
  }
}
